from django.contrib.auth.hashers import make_password
from rest_framework.views import APIView
from .models import UserInfo
from utils.jsonResponse import ErrorResponse, DetailResponse, SuccessResponse
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from utils.common import REGEX_USERNAME, get_parameter_dic,REGEX_PASSWORD
import re
from .serializers import UserSerializer, ManagedClassSerializer,ClassInfoSerializer
from ..student.models import StudentInfo, ClassInfo
from ..student.serializers import StudentInfoSerializer
from ..teacher.models import TeacherInfo, TeachingInfo

# ================================================= #
# ************** 前端用户登录 view  ************** #
# ================================================= #

'''
前端用户登录
post:
【功能描述】用户登录</br>
【参数说明】username为账号</br>
【参数说明】password为密码</br>
'''



class UsernamePassWordLoginView(APIView):
    """
    post:
    账号密码登录(手机号)此种方式传参通用
    【功能描述】账号密码登录</br>
    【参数说明】username 账号</br>
    【参数说明】password 密码</br>
       """

    def post(self, request, *args, **kwargs):
        account = get_parameter_dic(request)['userName']
        password = get_parameter_dic(request)['passWord']
        # 验证手机号是否合法
        if not re.match(REGEX_USERNAME, account):
            return ErrorResponse(msg="请输入正确用户名")
        user = UserInfo.objects.filter(Account=account).first()
        if user and user.check_Password(password):  # check_password() 对明文进行加密,并验证
            resdata = APPMobileSMSLoginSerializer.get_token(user)
            resdata['userInfo'] = UserSerializer(user).data
            return DetailResponse(data=resdata, msg="登录成功")
        return ErrorResponse(msg="账号或密码错误")


'''
前端用户注册
post:
【功能描述】用户注册</br>
【参数说明】username为账号</br>
【参数说明】password为密码</br>
【参数说明】password2为确认输入的密码</br>
'''


class RegisterView(APIView):
    def post(self, request, *args, **kwargs):
        account = get_parameter_dic(request)['account']
        password = get_parameter_dic(request)['password']
        password2 = get_parameter_dic(request)['password2']
        if account is None or password is None or password2 is None:
            return ErrorResponse(msg="提交的参数不能为空")
        # 判断密码是否合法
        if len(password) < 6:
            return ErrorResponse(msg="密码长度至少6位")

        if not re.match(REGEX_PASSWORD, password):
            return ErrorResponse(msg="密码格式不正确(大小写字母、数字组合)")

        if password != password2:
            return ErrorResponse(msg="两次密码输入不一致")

        # 验证用户名是否合法
        if not re.match(REGEX_USERNAME,  account):
            return ErrorResponse(msg="用户名格式错误")

        if UserInfo.objects.filter(Account=account).exists():
            return ErrorResponse(msg="用户名已存在")
        else:
            # 开始注册
            UserInfo.objects.create(Account=account, password=make_password(password))
            return SuccessResponse(msg="注册成功")

class APPMobileSMSLoginSerializer(TokenObtainPairSerializer):
    """
    登录的序列化器:
    重写djangorestframework-simplejwt的序列化器
    """

    @classmethod
    def get_token(cls, user):
        refresh = super(APPMobileSMSLoginSerializer, cls).get_token(user)
        data = {}
        data['userId'] = user.id
        data['refresh'] = str(refresh)
        data['token'] = str(refresh.access_token)
        return data
# """
# 手机号密码登录
# """
#
#
# class AppMoliePasswordLoginSerializer(TokenObtainPairSerializer):
#     """
#     前端登录的序列化器:
#     重写djangorestframework-simplejwt的序列化器
#     """
#
#     default_error_messages = {
#         'no_active_account': _('该账号已被禁用,请联系管理员')
#     }
#
#     def validate(self, attrs):
#         mobile = attrs['username']
#         # 验证手机号是否合法
#         if not re.match(REGEX_MOBILE, mobile):
#             result = {
#                 "code": 4000,
#                 "msg": "请输入正确的手机号",
#                 "data": None
#             }
#             return result
#         password = attrs['password']
#         user = Users.objects.filter(username=mobile, identity=2).first()
#         if user and not user.is_active:
#             result = {
#                 "code": 4000,
#                 "msg": "该账号已被禁用,请联系管理员",
#                 "data": None
#             }
#             return result
#         if user and user.check_password(password):  # check_password() 对明文进行加密,并验证
#             # data = super().validate(attrs)
#             data = {}
#             refresh = self.get_token(user)
#             data['identity'] = ast_convert(user.identity)
#             data['userId'] = user.id
#             data['refresh'] = str(refresh)
#             data['access'] = str(refresh.access_token)
#             result = {
#                 "code": 2000,
#                 "msg": "登录成功",
#                 "data": {
#                     "page": 1,
#                     "limit": 1,
#                     "total": 1,
#                     "data": data
#                 },
#             }
#         else:
#             result = {
#                 "code": 4000,
#                 "msg": "账号/密码不正确",
#                 "data": None
#             }
#         return result
#
#
# class APPMobilePasswordLoginView(TokenObtainPairView):
#     """
#     手机号密码登录接口（此种方式传参需要formdata方式）
#     """
#     serializer_class = AppMoliePasswordLoginSerializer
#     permission_classes = []
#
#
# #发送短信序列化器
# class SmsSerializer(serializers.Serializer):
#     mobile = serializers.CharField(max_length=11, required=True, help_text="手机号")
#     smstype = serializers.CharField(max_length=10, required=True, help_text="请求类型：login/register/restpass/rebind")
#
#     # 函数名必须：validate + 验证字段名
#     def validate_mobile(self, mobile):
#         """
#         手机号码验证
#         """
#         # 是否合法手机号
#         if not re.match(REGEX_MOBILE, mobile):
#             raise serializers.ValidationError("手机号码非法", 400)
#
#         if self.context['smstype'] == "register":  #用户注册
#             # 是否已经注册
#             if Users.objects.filter(mobile=mobile).count():
#                 raise serializers.ValidationError("该手机号已注册", 400)
#
#         if self.context['smstype'] == "restpass" or self.context['smstype'] == "login":  #重置密码/用户登录
#             #该手机号是否已注册
#             if not Users.objects.filter(username=mobile, identity=2, is_active=True).count():
#                 raise serializers.ValidationError("没有找到该用户或已禁用", 400)
#
#         if self.context['smstype'] == "wxbind":  #微信绑定
#             #该手机号是否已注册
#             if not Users.objects.filter(username=mobile, mobile=mobile, identity=2, is_active=True,
#                                         oauthwxuser__isnull=True).count():
#                 raise serializers.ValidationError("没有找到该用户或该用户已绑定微信", 400)
#
#         if self.context['smstype'] == "rebind":  #换绑手机号，前提用户已经登录
#             #是否跟原来绑定过的号码一致
#             mqueryset = Users.objects.filter(id=self.context['request'].user.id)
#             if not mqueryset:
#                 raise serializers.ValidationError("该用户不存在", 400)
#             if mqueryset[0].mobile == mobile:
#                 raise serializers.ValidationError("请使用新的手机号绑定", 400)
#             if Users.objects.filter(mobile=mobile).count():
#                 raise serializers.ValidationError("该手机号已被其他用户绑定", 400)
#
#         return mobile
#

#
#
# class APPMobileSMSLoginView(APIView):
#     """
#     post:
#     手机号短信登录接口
#     【功能描述】用户手机号短信验证码登录</br>
#     【参数说明】mobile为手机号</br>
#     【参数说明】code短信验证码</br>
#     """
#     authentication_classes = []
#     permission_classes = []
#
#     def post(self, request):
#         mobile = get_parameter_dic(request)['mobile']
#         code = get_parameter_dic(request)['code']
#         # 验证手机号是否合法
#         if not re.match(REGEX_MOBILE, mobile):
#             return ErrorResponse(msg="请输入正确手机号")
#         # 判断短信验证码是否正确
#         redis_conn = get_redis_connection('verify_codes')
#         send_flag = redis_conn.get('sms_%s' % mobile)  # send_flag的值为bytes，需要转换成str ,send_flag.decode()
#         if not send_flag:  # 如果取不到标记，则说明验证码过期
#             return ErrorResponse(msg="短信验证码已过期")
#         else:
#             if str(send_flag.decode()) != str(code):
#                 return ErrorResponse(msg="验证码错误")
#             #开始登录
#             user = Users.objects.filter(username=mobile, identity=2).first()
#             if not user:
#                 return ErrorResponse(msg="用户不存在")
#             if not user.is_active:
#                 return ErrorResponse(msg="该账号已被禁用，请联系管理员")
#             resdata = APPMobileSMSLoginSerializer.get_token(user)
#             redis_conn.delete('sms_%s' % mobile)
#             return SuccessResponse(data=resdata, msg="登录成功")
#
#
# #用户忘记密码重置密码
# class ForgetPasswdResetView(APIView):
#     '''
#     post:
#     【功能描述】重置用户密码</br>
#     【参数说明】mobile为手机号</br>
#     【参数说明】code短信验证码</br>
#     【参数说明】password为密码</br>
#     '''
#     authentication_classes = []
#     permission_classes = []
#
#     def post(self, request, *args, **kwargs):
#
#         mobile = get_parameter_dic(request)['mobile']
#         code = get_parameter_dic(request)['code']
#         password = get_parameter_dic(request)['password']
#         if len(password) < 6:
#             return ErrorResponse(msg="密码长度至少6位")
#
#         # 验证手机号是否合法
#         if not re.match(REGEX_MOBILE, mobile):
#             return ErrorResponse(msg="请输入正确手机号")
#         # 判断短信验证码是否正确
#         redis_conn = get_redis_connection('verify_codes')
#         send_flag = redis_conn.get('sms_%s' % mobile)  #send_flag的值为bytes，需要转换成str ,,send_flag.decode()
#         if not send_flag:  # 如果取不到标记，则说明验证码过期
#             return ErrorResponse(msg="短信验证码已过期")
#         else:
#             if str(send_flag.decode()) != str(code):
#                 return ErrorResponse(msg="验证码错误")
#             #开始更换密码
#             user = Users.objects.filter(username=mobile, identity=2).first()
#             if not user:
#                 return ErrorResponse(msg="用户不存在")
#             if not user.is_active:
#                 return ErrorResponse(msg="该账号已被禁用，请联系管理员")
#             # 重置密码
#             user.password = make_password(password)
#             user.save()
#             redis_conn.delete('sms_%s' % mobile)
#             return SuccessResponse(msg="success")
